﻿function AzureStorageTablesApi(credentials, channel) {
    
    var self = this;

    function getBaseUrl() {
        return credentials.getTablesUrl();
    }

    function onError(request) {
        var responeText = request.responseText;
    }

    function execute(request, options) {
        request.sign(credentials);

        return channel.send(request, function (data, req) {
            if (options && options.success) options.success(data, req);
        }, function (data, req) {
            onError(req);
            var action = 'notify';
            if (options && options.error) action = options.error(data, req);
            if (action == 'notify') {
                notificationArea.showError(req.statusText);
            }
        }, function () {
        });
    }
    
    function getUri(relPath) {
        relPath = relPath || '';
        return new Uri().parse(getBaseUrl() + relPath);
    }
    
    var requests = {
        queryTables: function () {
            var request = new AzureRequest();
            request.verb = 'GET';
            request.uri = getUri('tables/');
            request.headers.Date = request.headers['x-ms-date'];
            delete request.headers['x-ms-date'];
            request.headers['x-ms-version'] = '2009-07-17';
            request.signatureType = 'SharedKeyTables';
            return request;
        },
        createTable: function (options) {
            var content = options.content;
            var contentBytes = new UTF8().getBytes(content);

            var request = new AzureRequest();
            request.verb = 'POST';
            request.uri = getUri('tables');

            request.headers.DataServiceVersion = '1.0;NetFx';
            request.headers.MaxDataServiceVersion = '1.0;NetFx';

            request.headers['Content-Type'] = 'application/atom+xml';
            request.headers['Content-Length'] = contentBytes.length;
            request.headers.Date = request.headers['x-ms-date'];
            request.signatureType = 'SharedKeyLiteTables';
            request.data = content;
            return request;
        },
        deleteTable: function (options) {
            var table = options.table;

            var request = new AzureRequest();
            request.verb = 'DELETE';
            request.uri = getUri('tables(\'' + table + '\')');

            request.headers.DataServiceVersion = '1.0;NetFx';
            request.headers.MaxDataServiceVersion = '1.0;NetFx';

            request.headers['Content-Type'] = 'application/atom+xml';
            request.headers.Date = request.headers['x-ms-date'];
            request.signatureType = 'SharedKeyLiteTables';
            return request;
        },
        query: function (options) {
            var table = options.table;

            var request = new AzureRequest();
            request.verb = 'GET';
            request.uri = getUri(table + '()');

            request.headers.DataServiceVersion = '1.0;NetFx';
            request.headers.MaxDataServiceVersion = '1.0;NetFx';

            request.headers.Date = request.headers['x-ms-date'];
            request.signatureType = 'SharedKeyLiteTables';

            if (options.top != undefined) {
                request.addQuery('$top', options.top);
            }
            if (options.filter) {
                request.addQuery('$filter', options.filter);
            }
            return request;
        },
        insertEntity: function (options) {
            var table = options.table;
            var content = options.content;
            var contentBytes = new UTF8().getBytes(content);

            var request = new AzureRequest();
            request.verb = 'POST';
            request.uri = getUri(table);

            request.headers['Content-Type'] = 'application/atom+xml';
            request.headers['Content-Length'] = contentBytes.length;

            request.headers.DataServiceVersion = '1.0;NetFx';
            request.headers.MaxDataServiceVersion = '1.0;NetFx';

            request.headers.Date = request.headers['x-ms-date'];
            request.signatureType = 'SharedKeyLiteTables';

            request.data = content;
            return request;
        },
        updateEntity: function (options) {
            var table = options.table;
            var partitionKey = options.partitionKey;
            var rowKey = options.rowKey;
            var content = options.content;
            var contentBytes = new UTF8().getBytes(content);

            var request = new AzureRequest();
            request.verb = 'PUT';
            request.uri = getUri(table + '(PartitionKey=\'' + partitionKey + '\',RowKey=\'' + rowKey + '\')');

            request.headers['Content-Type'] = 'application/atom+xml';
            request.headers['Content-Length'] = contentBytes.length;

            request.headers.DataServiceVersion = '1.0;NetFx';
            request.headers.MaxDataServiceVersion = '1.0;NetFx';
            request.headers['If-Match'] = '*';
            
            request.headers.Date = request.headers['x-ms-date'];
            request.signatureType = 'SharedKeyLiteTables';

            request.data = content;
            return request;
        },
        deleteEntity: function (options) {
            var table = options.table;
            var partitionKey = options.partitionKey;
            var rowKey = options.rowKey;

            var request = new AzureRequest();
            request.verb = 'DELETE';
            request.uri = getUri(table + '(PartitionKey=\'' + partitionKey + '\',RowKey=\'' + rowKey + '\')');

            request.headers.DataServiceVersion = '1.0;NetFx';
            request.headers.MaxDataServiceVersion = '1.0;NetFx';
            request.headers['If-Match'] = '*';

            request.headers.Date = request.headers['x-ms-date'];
            request.signatureType = 'SharedKeyLiteTables';

            return request;
        },
        getServiceProperties: function () {
            var request = new AzureRequest();
            request.verb = 'GET';
            request.uri = getUri();
            request.addQuery('restype', 'service');
            request.addQuery('comp', 'properties');

            request.headers.DataServiceVersion = '1.0;NetFx';
            request.headers.MaxDataServiceVersion = '1.0;NetFx';
            request.headers.Date = request.headers['x-ms-date'];
            request.signatureType = 'SharedKeyLiteTables';
            return request;
        },
        setServiceProperties: function (options) {
            var content = options.content;
            var contentBytes = new UTF8().getBytes(content);
            
            var request = new AzureRequest();
            request.verb = 'PUT';
            request.uri = getUri();
            
            request.addQuery('restype', 'service');
            request.addQuery('comp', 'properties');

            request.headers['Content-Type'] = 'application/xml';
            request.headers['Content-Length'] = contentBytes.length;
            request.data = options.content;

            request.headers.DataServiceVersion = '1.0;NetFx';
            request.headers.MaxDataServiceVersion = '1.0;NetFx';
            request.headers.Date = request.headers['x-ms-date'];
            request.signatureType = 'SharedKeyLiteTables';
            return request;
        }
    };
    
    function queryTables(options) {
        var request = requests.queryTables(options);
        execute(request, options);
    }

    function createTable(options) {
        var request = requests.createTable(options);
        execute(request, options);
    }

    function removeTable(options) {
        var request = requests.deleteTable(options);
        execute(request, options);
    }

    function query(options) {
        var request = requests.query(options);
        execute(request, options);
    }

    function insertEntity(options) {
        var request = requests.insertEntity(options);
        execute(request, options);
    }
    
    function updateEntity(options) {
        var request = requests.updateEntity(options);
        execute(request, options);
    }

    function deleteEntity(options) {
        var request = requests.deleteEntity(options);
        execute(request, options);
    }
    
    function getServiceProperties(options) {
        var request = requests.getServiceProperties(options);
        execute(request, options);
    }

    function setServiceProperties(options) {
        var request = requests.setServiceProperties(options);
        execute(request, options);
    }
    
    self.requests = requests;
    self.queryTables = queryTables;
    self.createTable = createTable;
    self.removeTable = removeTable;
    self.query = query;
    self.insertEntity = insertEntity;
    self.updateEntity = updateEntity;
    self.deleteEntity = deleteEntity;
    self.getServiceProperties = getServiceProperties;
    self.setServiceProperties = setServiceProperties;

}